package edu.hitwh.controller;

import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;

import edu.hitwh.record.BookRecord;
import edu.hitwh.repository.BookQuery;
import edu.hitwh.service.BookService;
import edu.hitwh.wrapper.Resp;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import lombok.RequiredArgsConstructor;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@RestController
@RequestMapping("/book")
@RequiredArgsConstructor
@RateLimiter(name = "default-ratelimiter")
@Bulkhead(name = "default-bulkhead")
@CircuitBreaker(name = "default-circuitbreaker")
public class BookController {
    private final BookService bookService;

    @GetMapping("/search")
    public Resp<Page<BookRecord>> searchBooks(
            @RequestParam(required = false) String title,
            @RequestParam(required = false) String author,
            @RequestParam(required = false) String isbn,
            @RequestParam(required = false) Boolean available,
            @PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC) Pageable pageable
    ) {
        BookQuery query = BookQuery.builder()
                .title(title)
                .author(author)
                .isbn(isbn)
                .available(available)
                .build();
        return Resp.success(bookService.searchBooks(query, pageable)
                        .map(BookRecord::fromEntity));
    }

    @PostMapping("")
    public Resp<BookRecord> createBook(@RequestBody BookRecord bookRecord) {
        bookService.createBook(bookRecord.toEntity());
        return Resp.success(bookRecord);
    }

    @DeleteMapping("/{id}")
    public Resp<Boolean> removeBook(@PathVariable Long id) {
        bookService.removeBook(id.intValue());
        return Resp.success(true);
    }

    @PutMapping("/{id}/addCopies")
    public Resp<Boolean> addCopies(@PathVariable Long id, @RequestParam Integer copies) {
        bookService.addCopies(id, copies);
        return Resp.success(true);
    }

    @PutMapping("/{id}/removeCopies")
    public Resp<Boolean> removeCopies(@PathVariable Long id, @RequestParam Integer copies) {
        bookService.removeCopies(id, copies);
        return Resp.success(true);
    }


}
